﻿/*
 * Copyright 2009 BAKUDO Michał Rabiński	 
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package bakudo.utils.scrollers.smartScroll.scrollable {
	import bakudo.utils.scrollers.smartScroll.BakudoSmartScroll;

	import gs.TweenLite;
	import gs.easing.Cubic;

	/**
	 * @author Bakudo Michał Rabiński
	 */
	public class ScrollableItemVO {

		//::::::::::::::: public vars ::::::::::::::://
		
		//unique item index
		public var itemIndex : uint;

		//visual _scrollableItem's index in axsis X or axis Y
		public var itemAxisIndex : uint;

		//item's data
		public var data : Object;

		//when true, item is not considered in update method 
		public var excludeFromList : Boolean;

		//::::::::::::::: private vars ::::::::::::::://
		
		//position x of item
		private var _posX : Number;

		//position y of item
		private var _posY : Number;

		//reference to view
		private var _scrollableItem : ScrollableItem;

		//reference to main core
		private var core : BakudoSmartScroll;

		public function ScrollableItemVO(core : BakudoSmartScroll) {
			this.core = core;
		}

		//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
		// PUBLIC GETTERS
		//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
		public function get posX() : Number {
			return _posX;
		}

		public function get posY() : Number {
			return _posY;
		}

		//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
		// PUBLIC SETTERS
		//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
		//sets x position in model
		public function set posX(pos : Number) : void {
			_posX = pos;
			update();
		}

		//sets y position in model
		public function set posY(pos : Number) : void {
			_posY = pos;
			update();
		}

		//sets reference to view
		public function set scrollableItem(item : ScrollableItem) : void {
			_scrollableItem = item;
			_scrollableItem.itemIndex = itemIndex;
			_scrollableItem.itemModel = this;
		}

		//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
		// PUBLIC METHODS
		//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
		
		/**
		 * changes position of itemVO and his scrollableItem displayObject
		 * @param	posX - position on x axis
		 * @param	posY - position on y axis
		 * @param	smooth - if true, use tween
		 */
		public function changePosition(posX : Number , posY : Number,smooth : Boolean = false) : void {
			
			if (smooth) {
				TweenLite.to(this, 1.6, {posX : posX, posY : posY, ease:Cubic.easeOut}); 
			} else {
				this.posX = posX;
				this.posY = posY;
			}
		}

		/**
		 * refreshes view, deleting or adding view based on position view is in
		 * if item view coexist within mask boundary then it adds item view
		 * if item coexist outside mask boundary then it deletes item view
		 * form container if it's not deleted yet
		 */
		public function update() : void {
			var safeGap : Number = 20;
			if(_posX < 0 - core.itemWidth - safeGap) {
				removeDisplayItem();	
			}else if(_posX > core.viewRect.width + safeGap) {
				removeDisplayItem();
			}else if (_posY < 0 - core.itemHeight - safeGap) {
				removeDisplayItem();
			}else if (_posY > core.viewRect.height + safeGap) {
				removeDisplayItem();
			} else if(!excludeFromList) {
				addDisplayItem();	
			}else if (excludeFromList) {
				removeDisplayItem();
			}
		}

		/**
		 * dispatch handleElementReady in view class in moment when
		 * all operations on this item in BakudoSmartScroll populate 
		 * method are done
		 */
		public function handleElementReady() : void { 
			_scrollableItem.handleElementReady();
		}

		//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
		// PRIVATE METHODS
		//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
		
		/**
		 * checks if item is allready added
		 */
		private function itemIsAdded() : Boolean {
			return core.itemsContainer && _scrollableItem.parent;
		}

		/**
		 * checks if item is allready removed
		 */
		private function itemIsRemoved( ) : Boolean {
			return core.itemsContainer && !_scrollableItem.parent;
		}

		/**
		 * deletes view from container
		 */
		private function removeDisplayItem() : void {
			if(itemIsAdded()) {
				core.itemsContainer.removeChild(_scrollableItem);
			}
		}

		/**
		 * adds view to container
		 */
		private function addDisplayItem() : void {
			if(itemIsRemoved()) {
				core.itemsContainer.addChild(_scrollableItem);
			}
			if(_scrollableItem.parent) {
				_scrollableItem.x = _posX;
				_scrollableItem.y = _posY;
			}
		}
	}
}
